<template>
  <div class="box" v-if="songDetail">
    <div
      class="bg"
      :style="{ backgroundImage: 'url(' + songDetail[0].al.picUrl + ')' }"
    ></div>
    <header>
      <div class="downArrow" @click="exitLyrics">
        <img class="auto-img" src="../assets/downArrow.png" alt="" />
      </div>
      <div class="header_title">
        <p>{{ songDetail[0].name }}</p>
        <div>
          <p v-for="ar in songDetail[0].ar" :key="ar.id">{{ ar.name }}</p>
        </div>
      </div>
      <div class="header_pic">
        <div class="header_pic1">
          <img class="auto-img" :src="songDetail[0].al.picUrl" alt="" />
        </div>
        <div class="header_pic2">
          <img class="auto-img" src="../assets/share.png" alt="" />
        </div>
      </div>
    </header>

    <KeepAlive>
      <main
        ref="main"
        @click="toggleMode"
        :class="{ toggle: isLyric, mask: !isLyric }"
      >
        <div v-show="isLyric" class="dvn" :class="{ active: playing }">
          <img class="auto-img" src="../assets/dvn.png" alt="" />
        </div>
        <div v-show="showPic">
          <div
            v-show="isLyric"
            class="record"
            :class="{ running: playing, pause: !playing }"
          >
            <div class="record_pic1">
              <img class="auto-img" src="../assets/dta.png" alt="" />
            </div>
            <div class="record_pic2">
              <img class="auto-img" :src="songDetail[0].al.picUrl" alt="" />
            </div>
          </div>
        </div>
        <div v-show="!showPic" class="loading">
          <img class="auto-img" src="../assets/loading.gif" alt="" />
        </div>

        <div v-show="!isLyric">
          <div
            ref="lyricRegion"
            :style="{
              transform: 'translateY(' + updateIdx * 30 + 'px)',
            }"
          >
            <ul
              class="lyricList"
              ref="lyricList"
              :style="{ transform: 'translateY(' + deviation + ')' }"
              @touchstart="startCoordinate"
              @touchmove="moveCoordinate"
            >
              <li
                v-for="(row, index) in lyric"
                :class="{ lyricActive: lyricActiveIndex == index }"
                :key="index"
              >
                <span
                  :class="{ activeP: !playing }"
                  :style="{ animationDuration: rowTimes[index] + 's' }"
                  >{{ groups[index].text }}</span
                >
              </li>
            </ul>
          </div>
        </div>
        <div class="middle" :class="{ hidden: isHidden }">
          <svg
            t="1636863907545"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="2421"
            width="20"
            height="20"
            @click="updateTime"
          >
            <path
              d="M891.161 512l-749.992 450v-900l749.992 450z"
              p-id="2422"
              fill="#27e3f0"
            ></path>
          </svg>
          <div class="middle-line"></div>
          <span class="middle-time">{{
            countTime(updateT) || countTime(currentTime)
          }}</span>
        </div>
      </main>
    </KeepAlive>

    <footer>
      <!-- <div class="functionOptions">
          <div class="icon heart">
            <img class="auto-img" src="../assets/heart.png" alt="">
          </div>
          <div class="icon download">
            <img class="auto-img" src="../assets/download.png" alt="">
          </div>
          <div class="icon 1">
            <img class="auto-img" src="../assets/comment.png" alt="">
          </div>
          <div class="icon comment">
            <img class="auto-img" src="../assets/comment.png" alt="">
          </div>
          <div class="icon more">
            <img class="auto-img" src="../assets/listLoop.png" alt="">
          </div>
      </div> -->
      <div class="range">
        <input
          type="range"
          min="0"
          :max="duration"
          v-model="value"
          @change="changeCurrentTime"
          @input="ipting = true"
        />
        <span ref="rangeShow" :style="{ width: percentage }"></span>
        <span>{{ countTime(currentTime) }}</span>
        <span>{{ countTime(duration) }}</span>
      </div>
      <div class="playingMode">
        <ul @click="showList">
          <li class="mode" v-if="'list' == currentType">
            <img class="auto-img" src="../assets/listLoop.png" alt="" />
          </li>
          <li class="mode" v-if="'order' == currentType">
            <img class="auto-img" src="../assets/duq.png" alt="" />
          </li>
          <li class="mode single" v-if="'single' == currentType">
            <img class="auto-img" src="../assets/single.png" alt="" />
          </li>
          <li class="mode" v-if="'random' == currentType">
            <img class="auto-img" src="../assets/dv7.png" alt="" />
          </li>
        </ul>
        <div class="mode" @click="previous">
          <img class="auto-img" src="../assets/previous.png" alt="" />
        </div>
        <div
          class="mode playing"
          v-if="playing"
          @click="$emit('on-pause', false)"
        >
          <img class="auto-img" src="../assets/pause.png" alt="" />
        </div>
        <div class="mode playing" v-else @click="$emit('on-playing', true)">
          <img class="auto-img" src="../assets/playing.png" alt="" />
        </div>
        <div class="mode" @click="nextSong">
          <img class="auto-img" src="../assets/next.png" alt="" />
        </div>
        <div class="mode" @click="ejectList">
          <img class="auto-img" src="../assets/dvd.png" alt="" />
        </div>

        <ul class="playType" :class="{ toggle: isShow }">
          <li v-if="!('list' == currentType)" @click="toggleType('list')">
            <div><img src="../assets/listLoop.png" alt="" /></div>
            <span>列表循环</span>
          </li>
          <li @click="toggleType('order')" v-if="!('order' == currentType)">
            <div><img src="../assets/duq.png" alt="" /></div>
            <span>顺序播放</span>
          </li>
          <li @click="toggleType('single')" v-if="!('single' == currentType)">
            <div><img src="../assets/single.png" alt="" /></div>
            <span>单曲循环</span>
          </li>
          <li @click="toggleType('random')" v-if="!('random' == currentType)">
            <div><img src="../assets/dv7.png" alt="" /></div>
            <span>随机播放</span>
          </li>
        </ul>
      </div>
    </footer>
  </div>
</template>

<script>
export default {
  props: {
    playing: Boolean,
    duration: Number,
    currentTime: Number,
    playLists: [Object, Array],
    currentType: String,
    songId: Number,
  },
  data() {
    return {
      songDetail: null,
      value: this.currentTime,
      ipting: false,
      isLyric: true,
      lyric: "",
      lyricActiveIndex: null,
      deviation: 0,
      rowTimes: [],
      groups: [],
      toggleId: null,
      isShow: false,
      showPic: false,
      start: null,
      move: null,
      updateIdx: null,
      updateT: null,
      middle: null,
      isHidden: true,
      timeout: null,
    };
  },
  methods: {
    exitLyrics() {
      this.$emit("exit-lyrics", false);
    },
    changeCurrentTime() {
      this.$emit("updata-current-time", this.value);
      this.ipting = false;
    },
    toggleMode() {
      this.isLyric = !this.isLyric;
    },
    ejectList() {
      this.$emit("is-play-list", !this.isPlayList);
    },
    nextSong() {
      if (this.playLists.tracks) {
        var idx = this.playLists.tracks
          .map((item) => {
            if (item.id == this.$route.query.id) {
              return item.id;
            }
          })
          .indexOf(this.songId);
        switch (this.currentType) {
          case "order":
            if (idx != -1) {
              if (idx == this.playLists.tracks.length - 1) {
                this.$emit("on-playing", false);
              } else {
                this.toggleId = this.playLists.tracks[idx + 1].id;
              }
            }
            break;
          case "single":
          case "list":
            if (idx != -1) {
              if (idx == this.playLists.tracks.length - 1) {
                this.toggleId = this.playLists.tracks[0].id;
              } else {
                this.toggleId = this.playLists.tracks[idx + 1].id;
              }
            }
            break;
          case "random":
            var ran = parseInt(Math.random() * this.playLists.tracks.length);
            this.playLists.tracks.forEach(() => {
              while (this.playLists.tracks[ran].id == this.songId) {
                ran = parseInt(Math.random() * this.playLists.tracks.length);
              }
              this.toggleId = this.playLists.tracks[ran].id;
            });
            break;
        }
      } else {
        var idxB = this.playLists
          .map((item) => {
            if (item.id == this.$route.query.id) {
              return item.id;
            }
          })
          .indexOf(this.songId);
        switch (this.currentType) {
          case "order":
            if (idxB != -1) {
              if (idxB == this.playLists.length - 1) {
                this.$emit("on-playing", false);
              } else {
                this.toggleId = this.playLists[idxB + 1].id;
              }
            }
            break;
          case "single":
          case "list":
            if (idxB != -1) {
              if (idxB == this.playLists.length - 1) {
                this.toggleId = this.playLists[0].id;
              } else {
                this.toggleId = this.playLists[idxB + 1].id;
              }
            }
            break;
          case "random":
            var ranB = parseInt(Math.random() * this.playLists.length);
            this.playLists.forEach(() => {
              while (this.playLists[ranB].id == this.songId) {
                ranB = parseInt(Math.random() * this.playLists.length);
              }
              this.toggleId = this.playLists[ranB].id;
            });
            break;
        }
      }
    },
    previous() {
      if (this.playLists.tracks) {
        this.playLists.tracks.forEach((item, index) => {
          if (item.id == this.$route.query.id) {
            if (this.playLists.tracks[0].id == this.$route.query.id) {
              this.toggleId = this.playLists.tracks[
                this.playLists.tracks.length - 1
              ].id;
            } else {
              this.toggleId = this.playLists.tracks[index - 1].id;
            }
          }
        });
      } else {
        this.playLists.forEach((item, index) => {
          if (item.id == this.$route.query.id) {
            if (this.playLists[0].id == this.$route.query.id) {
              this.toggleId = this.playLists[this.playLists.length - 1].id;
            } else {
              this.toggleId = this.playLists[index - 1].id;
            }
          }
        });
      }
    },
    getSongDetail(id) {
      this.showPic = false;
      this.axios
        .get("https://apis.netstart.cn/music/song/detail?ids=" + id)
        .then((res) => {
          this.songDetail = res.data.songs;
          window.setTimeout(() => {
            this.showPic = true;
          }, 2000);
        });
    },
    getLyric(id) {
      this.axios
        .get("https://apis.netstart.cn/music/lyric?id=" + id)
        .then((res) => {
          this.lyric = res.data.lrc.lyric
            .trim()
            .split("\n")
            .filter((s) => s);
        });
    },
    toggleType(type) {
      this.$emit("toggle-type", type);
      this.isShow = !this.isShow;
    },
    showList() {
      this.isShow = !this.isShow;
    },
    startCoordinate(e) {
      this.start = e.targetTouches[0].clientY;
    },
    moveCoordinate(e) {
      this.$refs.lyricRegion.style.transition = "transform 0.5s";
      this.move = e.targetTouches[0].clientY;
    },
    countTime(t) {
      if (t) {
        if (Math.floor(t / 60) >= 10) {
          if (Math.floor((t % 60).toFixed(0)) >= 10) {
            return Math.floor(t / 60) + ":" + Math.floor((t % 60).toFixed(0));
          } else {
            return (
              Math.floor(t / 60) + ":" + "0" + Math.floor((t % 60).toFixed(0))
            );
          }
        } else {
          if (Math.floor((t % 60).toFixed(0)) >= 10) {
            return (
              "0" + Math.floor(t / 60) + ":" + Math.floor((t % 60).toFixed(0))
            );
          } else {
            return (
              "0" +
              Math.floor(t / 60) +
              ":" +
              "0" +
              Math.floor((t % 60).toFixed(0))
            );
          }
        }
      }
    },
    updateTime() {
      this.isLyric = true;
      this.$refs.lyricRegion.style.transition = "none";
      if (this.groups[0]) {
        this.groups.forEach((item, index) => {
          if (this.lyricActiveIndex - this.updateIdx == index) {
            this.$emit("updata-current-time", item.time);
            this.$refs.lyricRegion.style.transform = "none";
            this.updateT = null;
          }
        });
      }
    },
  },
  computed: {
    percentage() {
      return (this.value / this.duration) * 100 + "%";
    },
  },
  watch: {
    currentTime(n) {
      if (!this.ipting) {
        this.value = n;
      }
      if (this.groups[0]) {
        this.groups.forEach((item, index) => {
          if (n >= item.time) {
            this.lyricActiveIndex = index;
          }
        });
      }
    },
    lyricActiveIndex(n) {
      if (this.$refs.main.offsetHeight) {
        this.deviation =
          this.$refs.main.offsetHeight / 2 -
          Array.prototype.slice
            .call(this.$refs.lyricList.querySelectorAll("li"), 0, n)
            .reduce(function (total, item) {
              return total + item.offsetHeight;
            }, 0) +
          "px";
      }
    },
    lyric() {
      this.groups = this.lyric
        .map((item) => {
          var match = item.match(
            /^\[(?<time>\d{2}:\d{2}\.\d{2,3})\] *(?<text>.*)$/im
          );
          if (match) {
            return match.groups;
          }
        })
        .map((item) => {
          var match = item.time.match(/^(?<m>\d{2}):(?<s>\d{2}.\d{2,3})$/im);
          return {
            ...item,
            time: (match.groups.m * 60 + match.groups.s * 1).toFixed(3),
          };
        });
      for (let i = 1; i < this.groups.length; i++) {
        this.rowTimes.push(
          Number(this.groups[i].time) - Number(this.groups[i - 1].time)
        );
      }
      return this.groups;
    },
    toggleId(n) {
      this.$emit("play-audio", n);
    },
    songId(n) {
      this.$router.push({ path: "/playpage", query: { id: n } });
      this.getSongDetail(n);
      this.getLyric(n);
    },
    move(n) {
      this.updateIdx = Math.floor((n - this.start) / 30);
      this.isHidden = false;
      if (this.groups[0]) {
        this.groups.forEach((item, index) => {
          if (this.lyricActiveIndex - this.updateIdx == index) {
            this.updateT = item.time;
          }
        });
      }
      if (this.timeout) {
        window.clearTimeout(this.timeout);
        this.timeout = window.setTimeout(() => {
          this.isHidden = true;
          this.$refs.lyricRegion.style.transform = "none";
        }, 3000);
      } else {
        this.timeout = window.setTimeout(() => {
          this.isHidden = true;
          this.$refs.lyricRegion.style.transform = "none";
        }, 3000);
      }
    },
  },
  created() {
    this.getSongDetail(this.$route.query.id);
    this.getLyric(this.$route.query.id);
  },
};
</script>

<style lang="less" scoped>
@keyframes rotaryRecord {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
@keyframes textImage {
  from {
    background-position-x: 100%;
  }
  to {
    background-position-x: 0%;
  }
}
.auto-img {
  display: block;
  width: 100%;
  height: auto;
}
.box {
  width: 100vw;
  height: 100vh;
  padding: 10px;
  overflow: hidden;
  .bg {
    width: 100%;
    height: 100%;
    position: fixed;
    background: rgb(44, 44, 44);
    filter: blur(20px) brightness(0.8);
    transform: scale(1.8);
    z-index: -1;
  }
  header {
    // background-color: red;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .downArrow {
      width: 25px;
      // height: 10px;
    }
    .header_pic {
      display: flex;
      .header_pic1 {
        width: 25px;
        border-radius: 50%;
        overflow: hidden;
      }
      .header_pic2 {
        width: 25px;
        margin-left: 8px;
      }
    }

    .header_title {
      margin-top: -6px;

      & > p:first-of-type {
        color: #e1e2e4;
        font-size: 13px;
        display: -webkit-box;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
        overflow: hidden;
        max-width: 60vw;
      }
      div {
        display: flex;
        justify-content: center;
        font-size: 12px;
        display: -webkit-box;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
        overflow: hidden;
        p {
          color: #98a0a4;
        }
        p::after {
          content: " / ";
        }
        p:last-of-type {
          &::after {
            content: none;
          }
        }
      }
    }
  }

  main {
    height: 78vh;
    position: relative;
    margin-top: 10px;
    overflow: hidden;

    .middle {
      position: fixed;
      top: 83vw;
      left: 0;
      width: 100vw;
      display: flex;
      align-items: center;
      transform: scale(0.95);

      &.hidden {
        display: none;
      }
      .middle-icon {
        width: 20px;
      }
      .middle-line {
        border-bottom: 1px dashed #27e3f0;
        flex: 1;
      }
      span {
        font-size: 12px;
        color: #27e3f0;
      }
    }
    &.mask {
      mask-image: linear-gradient(
        to bottom,
        transparent 0% 5%,
        blue 15% 85%,
        transparent 95% 100%
      );
    }
    &.toggle {
      padding-top: 30vw;
    }
    .lyricList {
      color: white;
      transition: all 0.5s;
      li {
        line-height: 30px;
        &.lyricActive span {
          color: transparent;
          background-image: linear-gradient(
            to right,
            blue 0% 50%,
            yellow 53% 100%
          );
          background-clip: text;
          background-position-x: 100%;
          background-size: 200%;
          animation: textImage 2s linear;

          &.activeP {
            animation-play-state: paused;
          }
        }
      }
    }
    .dvn {
      width: 30vw;
      position: absolute;
      top: -20px;
      left: calc(50% - 30px);
      transform: rotate(-25deg);
      transform-origin: 19px 30px;
      z-index: 2;
      transition: transform 0.8s;
      &.active {
        transform: rotate(-3deg);
      }
    }

    .record {
      position: relative;
      width: 70vw;
      margin: 0 auto;
      background-color: rgba(255, 255, 255, 0.2);
      border-radius: 50%;
      animation: rotaryRecord 8s linear infinite;
      &.running {
        animation-play-state: running;
      }
      &.pause {
        animation-play-state: paused;
      }

      .record_pic1 {
        border-radius: 50%;
        overflow: hidden;
      }
      .record_pic2 {
        position: absolute;
        top: 16vw;
        left: 16vw;
        width: 38vw;
        height: 38vw;
        border-radius: 50%;
        overflow: hidden;
        margin: 2px;
      }
    }

    .loading {
      position: relative;
      width: 70vw;
      height: 70vw;
      margin: 0 auto;
      border-radius: 50%;
      padding: 2px;
    }
  }

  footer {
    width: 100%;
    // padding-top:3vh;
    position: fixed;
    bottom: 0;
    left: 0;
    .functionOptions {
      display: flex;
      justify-content: space-between;
      width: 70vw;
      margin: 0 auto;
      margin-bottom: 10px;
      .icon {
        width: 10vw;
      }
    }
    .range {
      width: 80vw;
      height: 2px;
      background-color: #ccc;
      margin: 0 auto;
      position: relative;
      transform: scale(0.9);
      span:nth-of-type(1) {
        display: block;
        height: 100%;
        background-color: cornflowerblue;
        position: relative;
        &::before {
          content: "";
          position: absolute;
          top: -5px;
          right: -5px;
          width: 10px;
          height: 10px;
          background-color: white;
          border-radius: 50%;
        }
      }
      span:nth-of-type(2) {
        position: absolute;
        top: -9px;
        left: -40px;
        color: white;
        transform: scale(0.7);
      }
      span:nth-of-type(3) {
        position: absolute;
        top: -9px;
        right: -40px;
        color: white;
        transform: scale(0.7);
      }
      input {
        position: absolute;
        height: 100%;
        top: 0;
        left: -2vw;
        // left:0vw;
        // width:80vw;
        width: 84vw;
        opacity: 0;
      }
    }
    .playingMode {
      width: 70vw;
      display: flex;
      justify-content: space-between;
      margin: 0 auto;
      padding: 20px 0;
      align-items: center;
      .mode {
        width: 36px;
        &.single {
          transform: scale(0.6);
        }
        &.playing {
          width: 60px;
          padding-bottom: 0;
        }
      }
    }
    .playType {
      position: absolute;
      bottom: 60px;
      left: 12vw;
      transform: scale(0.8);
      background-color: rgb(56, 56, 56);
      border-radius: 2vw;
      overflow: hidden;
      display: none;
      &.toggle {
        display: block;
      }

      li {
        display: flex;
        // width:33vw;
        align-items: center;
        justify-content: center;
        padding: 0 1vh;
        height: 40px;
        padding: 0 3vw;
        &:hover {
          background-color: black;
        }

        div {
          width: 10vw;
        }
        span {
          font-size: 12px;
          color: #e0d9e1;
          display: block;
        }
      }
    }
  }
}
</style>